package main

import "fmt"

func main() {
	userK := &User{
		name: "abc",
		age:  15,
	}

	userD := &User{
		"def", 20,
	}

	userCollection := &userCollection{
		users: []*User{userK, userD},
	}

	iterator := userCollection.createIterator()
	for iterator.hasNext() {
		user := iterator.getNext()
		fmt.Printf("user name %s, age : %d \n", user.name, user.age)
	}
}

type iterator interface {
	hasNext() bool
	getNext() *User
}

type collection interface {
	createIterator() iterator
}

type User struct {
	name string
	age  int
}

type userIterator struct {
	index int
	users []*User
}

func (ui *userIterator) hasNext() bool {
	return ui.index < len(ui.users)
}

func (ui *userIterator) getNext() *User {
	if ui.hasNext() {
		user := ui.users[ui.index]
		ui.index++
		return user
	}
	return nil
}

type userCollection struct {
	users []*User
}

func (u *userCollection) createIterator() iterator {
	return &userIterator{
		users: u.users,
	}
}

/*
迭代器模式在平时编程的时候使用的并不多，
像Java、C#编程时都自带了迭代器模式的实现，也支持实现语言内置的Iterator接口来给自定义集合创建迭代器。

关于迭代器的使用场景，我们只要记住它的主要思想是将集合对象的遍历操作从集合类中拆分出来，放到迭代器实现类中，
让两者的职责更单一的同时也让客户端不必关系该怎么去实现集合的迭代算法。
*/
